package net.huashitong.appsecurity;

import com.alibaba.fastjson.JSON;
import com.sirdc.modules.core.web.model.Message;
import com.sirdc.modules.utils.StringUtils;
import org.apache.shiro.web.filter.AccessControlFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author <a href="mailto:yhy23456@163.com">huiyang.yu</a>
 * @since 2017.08.21
 */
public class AppAuthcFilter extends AccessControlFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        String sign = request.getParameter(AppConstants.SIGN);
        String username = request.getParameter(AppConstants.USERNAME);
        String timestamp = request.getParameter(AppConstants.TIMESTAMP);
        if (sign == null || username == null || timestamp == null) {
            onLoginFail(response, "401", "参数校验失败");
            return false;
        }

        if (validTimestamp(timestamp)) {
            //时间戳检验失败
            onLoginFail(response, "401", "时间戳超时");
            return false;
        }

        //4、生成无状态Token
        AppToken token = new AppToken(username, sign, Long.parseLong(timestamp));

        try {
            //5、委托给Realm进行登录
            getSubject(request, response).login(token);
        } catch (Exception e) {
            //登录失败
            onLoginFail(response, "401", "检验签名失败");
            return false;
        }
        return true;
    }

    /**
     * 返回ture代表校验失败
     *
     * @param timestamp
     * @return
     */
    private boolean validTimestamp(String timestamp) {
        if (!StringUtils.isNumeric(timestamp)
                || System.currentTimeMillis() - Long.parseLong(timestamp) > 15000
                || System.currentTimeMillis() - Long.parseLong(timestamp) < -15000) {
            return true;
        }
        return false;
    }


    //登录失败时返回失败原因
    private void onLoginFail(ServletResponse response, String code, String message) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setStatus(HttpServletResponse.SC_OK);
        httpResponse.setHeader("Content-Type", "application/json;charset=UTF-8");
        Message msg = new Message();
        msg.setCode(code);
        msg.setMessage(message);
        String jsonString = JSON.toJSONString(msg);
        httpResponse.getWriter().write(jsonString);
    }
}
